<?php
declare(strict_types=1);

namespace App\Third\Service\Wx;


use App\Common\Constants\ErrorCode;
use App\Common\Service\BaseService;
use App\Pay\Service\PayService;
use Hyperf\Guzzle\ClientFactory;

/**
 * http://doc.wuuxiang.com/showdoc/web/#/11?page_id=54(三方文档地址)
 * Class WxPayService
 * @package App\Third\Service\Wx
 */
class WxPayService extends  BaseService
{
    /**
     * 通用支付下单接口url
     */
    const PAY_CANCEL_URL = '/external/commpay/CommPayCancelOnline.htm';

    /**
     * 通用支付下单接口url
     */
    const PAY_SUBMIT_URL = '/external/commpay/CommPaySubmit.htm';

    /**
     * 通用支付获取支付信息口url
     */
    const PAY_SUBMIT_CARD_URL = '/payrest/commpay/get/';

    /**
     * 通用支付下单接口url
     */
    const PAY_DO_PAY_URL = '/payrest/commpay/doPay';

    /**
     * 请求来源-客至提供
     */
    protected $SysType;

    /**
     * 接口根地址
     * @var string
     */
    protected $BaseUrl;

    /**
     * 商户编码-吾享提供
     */
    protected $AesKey;

    /**
     * 门店ID-吾享提供
     */
    protected $storeId;

    /**
     * 业务类型,DC:点餐,YD:预订,WS:外送,ZT:自提
     * buyTicket:购买券,rechargeCard:微信会员卡充值,upgradeCard:会员卡升级
     */
    protected $BuSiScopeNo;

    /**
     * 订单来源-吾享提供
     */
    protected $payFrom;

    /**
     * 小程序AppId
     */
    protected $AppId;

    /**
     * 小程序AppId绑定的商户ID
     */
    protected $MchId;

    /**
     * 订单成功支付回调通知地址
     */
    protected $udStateUrl;

    /**
     * http Client
     * @var
     */
    protected $httpClient;

    public function __construct(ClientFactory $clientFactory)
    {
        parent::__construct();
        if (env('APP_ENV') == 'dev') {
            $this->SysType = 'yiluxiaopao';
            $this->AesKey = 'DJTDLRH3R7M9BINRL5O2E6O7MJM8Y67Y';
            $this->BaseUrl = 'http://o2oapi.wuuxiang.com';
            $this->storeId = '176738';
            $this->BuSiScopeNo = 'WS';
            $this->payFrom = 330;
            $this->udStateUrl = 'https://ylxp-release-api.freshylxp.com/v1/api/payment/notify';
            $this->AppId = 'wx43a215392b89d41f';
            $this->MchId = '1578387751';
        } else {
            $this->SysType = 'yiluxiaopao';
            $this->AesKey = 'DJTDLRH3R7M9BINRL5O2E6O7MJM8Y67Y';
            $this->BaseUrl = 'http://o2oapi.wuuxiang.com';
            $this->storeId = '176738';
            $this->BuSiScopeNo = 'WS';
            $this->payFrom = 330;
            $this->udStateUrl = 'https://ylxp-api.huadingyun.cn/v1/api/payment/notify';
            $this->AppId = 'wx43a215392b89d41f';
            $this->MchId = '1578387751';
        }
        $this->httpClient = $clientFactory->create(['base_uri' => $this->BaseUrl, 'headers' => ['Content-Type' => 'application/json'], 'timeout' => 30.0]);
    }


    /**
     * 吾享通用支付下单
     * @param $orderNo
     * @param $openId
     * @param float $money
     * @return bool|mixed
     */
    public function comPaySubmit(string $orderNo, string $openId, float $money = 0.01)
    {
        $payS = $this->container->get(PayService::class);
        try {
            $temp_data['storeid'] = $this->storeId;
            $temp_data['orderid'] = $orderNo;
            $temp_data['payMoney'] = $money;
            $temp_data['trueMoney'] = $money;
            $temp_data['busiScopeNo'] = $this->BuSiScopeNo;
            $temp_data['payFrom'] = $this->payFrom;
            $temp_data['appid'] = $this->AppId;
            $temp_data['mpid'] = $this->MchId;
            $temp_data['udStateUrl'] = $this->udStateUrl;
            $post_data = [];
            $post_data['systype'] = $this->SysType;
            if ($temp_data) {
                $encrypt_data = $this->encrypt($temp_data);
                $post_data['data'] = $encrypt_data;
            }

            //3.1通用支付下单
            $api_return_data = $this->http_post_json(self::PAY_SUBMIT_URL, $post_data);
            $decrypt_data = $this->decrypt($api_return_data);
            $api_return_data = json_decode($decrypt_data, true);
            $data_arr['key'] = $api_return_data['key'];
            $data_arr['envType'] = 1;
            //3.7通用支付获取支付信息
            $url = self::PAY_SUBMIT_CARD_URL . $data_arr['key'] . '/0';
            $api_pay_info_data = json_decode($this->https_request($url), true);

            //3.8通用页面支付doPay
            $temp_data['money'] = $money;
            $temp_data['paytypeid'] = 6;
            $temp_data['payTypeProd'] = 'miniProgram';
            $temp_data['openid'] = $openId;
            $temp_data['cardsign'] = $api_pay_info_data['payinfo']['cardsign'];
            $api_return_do_pay_data = $this->do_request_post(self::PAY_DO_PAY_URL, json_encode($temp_data));
            $data_pay_info = json_decode($api_return_do_pay_data, true);
            if ($data_pay_info['returnCode'] != 1) {
                $content = ['exception'=> '吾享支付异常', 'errMsg' => $data_pay_info['errorText'], 'response' => $data_pay_info];
                $payS->writeLog('exception', $temp_data , $content, 'pay');
                return [
                    'code' => 0,
                    'errorCode' => ErrorCode::SYSTEM_INVALID,
                    'throw' => "吾享支付返回异常\n".__METHOD__ . ":line:".__LINE__."\n".
                        "订单编号[向下]\n{$orderNo}\n".
                        "请求参数[向下]\n". json_encode($temp_data) ."\n".
                        "请求返回[向下]\n{$api_return_do_pay_data}",
                    'msg' => '吾享支付失败'
                ];
            }
            $payS->writeLog('info', $temp_data, ['info' => '吾享支付成功', 'response' => $data_pay_info], 'pay');
            $payLoad = [
                'appId' => $data_pay_info['appId'],
                'timeStamp' => $data_pay_info['timeStamp'],
                'signType' => $data_pay_info['signType'],
                'package' => $data_pay_info['package'],
                'nonceStr' => $data_pay_info['nonceStr'],
                'paySign' => $data_pay_info['paySign'],
            ];
            return ['code' => 1, 'msg' => '支付下单成功', 'data' => $payLoad];

        }catch (\Exception $e){
            $line = $e->getLine();
            $error = $e->getMessage();
            $content = ['error' => '支付下单错误', 'errMsg' => $error];
            $payS->writeLog('error', $temp_data ,$content, 'pay');
            return [
                'code' => 0,
                'errorCode' => ErrorCode::SYSTEM_INVALID,
                'throw' => "吾享支付异常\n".__METHOD__ . ":line:{$line}\n".
                    "订单编号[向下]\n{$orderNo}\n".
                    "请求参数[向下]\n". json_encode($temp_data) . "\n".
                    "异常信息[向下]\n{$error}",
                'msg' => '吾享支付失败'
            ];
        }
    }
    /**
     * 通用支付订单撤销
     * @param $orderNo
     * @param float $money
     * @return mixed
     */
    public function comPayCancel(string $orderNo, $money = 0.01)
    {
        try {
            $temp_data['storeid'] = $this->storeId;
            $temp_data['paytypeid'] = 6;
            $temp_data['orderid'] = $orderNo;
            $temp_data['money'] = $money;
            $post_data = [];
            $post_data['systype'] = $this->SysType;
            if ($temp_data) {
                $encrypt_data = $this->encrypt($temp_data);
                $post_data['data'] = $encrypt_data;
            }
            //3.1通用支付订单撤销
            $post_url = self::PAY_CANCEL_URL;
            $api_return_data = $this->http_post_json($post_url, $post_data);
            $decrypt_data = $this->decrypt($api_return_data);
            $api_return_data = json_decode($decrypt_data, true);
            if ($api_return_data['returnCode'] != 1) {
                $content = json_encode(['param' => $temp_data, 'res' => $api_return_data], JSON_UNESCAPED_UNICODE);
                $this->write('吾享退款失败!--' . $api_return_data['errorText'], $content);
                return [
                    'code' => 0,
                    'errorCode' => ErrorCode::SYSTEM_INVALID,
                    'throw' => "吾享退款异常\n".__METHOD__ . ":line:".__LINE__."\n".
                        "订单编号[向下]\n{$orderNo}\n".
                        "请求返回[向下]\n{$api_return_data['errorText']}\n".
                        "异常信息[向下]\n{$content}",
                    'msg' => '吾享退款失败!--' . $api_return_data['errorText']
                ];
            }
            $this->write('吾享退款接口调用成功', json_encode(['param' => $temp_data, 'res' => $api_return_data]));
        } catch (\Exception $e) {
            $line = $e->getLine();
            $error = $e->getMessage();
            $content = json_encode(['param' => $temp_data, 'error' => $error], JSON_UNESCAPED_UNICODE);
            $this->write('吾享退款异常', $content);
            return [
                'code' => 0,
                'errorCode' => ErrorCode::SYSTEM_INVALID,
                'throw' => "吾享退款异常\n".__METHOD__ . ":line:{$line}\n".
                    "订单编号[向下]\n{$orderNo}\n".
                    "异常信息[向下]\n{$content}",
                'msg' => '吾享退款异常'
            ];
        }
        return ['code' => 1, 'msg' => '吾享退款接口调用成功', 'data' => $api_return_data];
    }
    /**
     * 加密 长数据加密(117)
     * @param array $originalData
     * @return string|void
     */
    public function encrypt($originalData)
    {
        $rsaPublicKey = $this->AesKey;
        $data = json_encode($originalData);
        $mess = WxCryptService::encrypt($data, $rsaPublicKey);
        return $mess;
    }
    /**
     * 解密 长数据解密(128)
     * @param string $encryptData
     * @return string|void
     */
    public function decrypt($encryptData)
    {
        $rsaPublicKey = $this->AesKey;
        $res = WxCryptService::decrypt($encryptData, $rsaPublicKey);
        return $res;
    }

}